package com.antd.admin.server.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.antd.admin.api.entity.SysMenu;
import com.antd.admin.api.entity.SysUser;
import com.antd.admin.api.vo.MenuTreeVo;
import com.antd.admin.api.vo.SysDeptTreeVo;
import com.antd.admin.server.mapper.SysMenuMapper;
import com.antd.admin.server.service.ISysMenuService;
import com.antd.admin.server.service.ISysRoleMenuService;
import com.antd.admin.server.service.ISysRoleService;
import com.antd.common.core.constant.Constant;
import com.antd.common.core.constant.MenuConstant;
import com.antd.common.core.exception.BaseException;
import com.antd.common.core.util.AntdMenuUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜单权限表 服务实现类
 * </p>
 *
 * @author 子丶沫
 * @since 2020-11-18
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {

    @Override
    public Set<String> findPermissionByUserId(String userId) {
        return baseMapper.findPermissionByUserId(userId);
    }

    @Override
    public List<String> findMenuIdByUserId(String userId) {
        return baseMapper.findMenuIdByUserId(userId);
    }

    @Override
    public List<SysMenu> findPermissionList(String userId) {
        return baseMapper.findPermissionList(userId);
    }


    @Override
    public JSONArray getRouters(String userId) {
        LambdaQueryWrapper<SysMenu> menuWrapper = Wrappers.<SysMenu>query().lambda();
        menuWrapper.
                select(SysMenu::getMenuId, SysMenu::getName, SysMenu::getPerms,SysMenu::getTitle, SysMenu::getPath, SysMenu::getParentId, SysMenu::getComponent, SysMenu::getIsFrame, SysMenu::getIcon, SysMenu::getSort, SysMenu::getType, SysMenu::getDelFlag,SysMenu::getAlwaysShow,SysMenu::getHidden,SysMenu::getRedirect,SysMenu::getKeepAlive,SysMenu::getRedirect);
        if(!Constant.PARENT_ID.equals(userId)){
            List<String> menuIdList = findMenuIdByUserId(userId);
            menuWrapper.in(SysMenu::getMenuId,menuIdList);
        }
        List<SysMenu> menuList = baseMapper.selectList(menuWrapper);
        JSONArray menuJsonArray = new JSONArray();
        AntdMenuUtil.getPermissionJsonArray(menuJsonArray,menuList,null);
        return menuJsonArray;
    }

    @Override
    public List<MenuTreeVo> getAllMenuList() {
        List<SysMenu> menuList = baseMapper.selectList(Wrappers.lambdaQuery());
        List<MenuTreeVo> treeVoList = menuList.stream()
                .filter(menu -> menu.getParentId().equals(Constant.PARENT_ID) && StrUtil.isNotBlank(menu.getParentId()))
                .map(m -> {
                    MenuTreeVo menuTreeVo = new MenuTreeVo();
                    BeanUtils.copyProperties(m, menuTreeVo);
                    menuTreeVo.setTitle(m.getName());
                    menuTreeVo.setParentName("一级菜单");
                    menuTreeVo.setParentId(Constant.PARENT_ID);
                    menuTreeVo.setValue(m.getMenuId());
                    return menuTreeVo;
                }).collect(Collectors.toList());
        AntdMenuUtil.findMenuChildren(treeVoList,menuList);
        return treeVoList;
    }

    @Override
    public int saveMenu(SysMenu menu) {
        verifyForm(menu);
        return baseMapper.insert(menu);
    }

    @Override
    public int updateMenu(SysMenu menu) {
        verifyForm(menu);
        return baseMapper.updateById(menu);
    }

    @Override
    public List<MenuTreeVo> searchMenu(String searchText) {
        List<SysMenu> menuList = baseMapper.selectList(Wrappers.<SysMenu>query().lambda().like(StrUtil.isNotBlank(searchText), SysMenu::getName, searchText));
        return menuList.stream()
                .peek(menu->{
                    String parentName = baseMapper.selectOne(Wrappers
                            .<SysMenu>query()
                            .lambda()
                            .select(SysMenu::getName)
                            .eq(SysMenu::getMenuId, menu.getParentId())).getParentName();
                    menu.setParentName(StrUtil.isNotBlank(parentName)?parentName:"一级菜单");
                })
                .map(menu -> {
                    MenuTreeVo menuTreeVo=new MenuTreeVo();
                    BeanUtils.copyProperties(menu,menuTreeVo);
                    menuTreeVo.setTitle(menu.getName());
                    menuTreeVo.setValue(menu.getMenuId());
                    return menuTreeVo;
                }).collect(Collectors.toList());
    }

    private void verifyForm(SysMenu menu){
        int parentType = MenuConstant.MenuType.CATALOG.getValue();
        if (!Constant.PARENT_ID.equals(menu.getParentId())) {
            SysMenu sysMenu = baseMapper.selectOne(Wrappers.<SysMenu>lambdaQuery().select(SysMenu::getType).eq(SysMenu::getMenuId, menu.getParentId()));
            parentType = sysMenu.getType();
        }
        //目录、菜单
        if (menu.getType() == MenuConstant.MenuType.CATALOG.getValue() ||
                menu.getType() == MenuConstant.MenuType.MENU.getValue()) {
            if (parentType != MenuConstant.MenuType.CATALOG.getValue()) {
                throw new BaseException("上级菜单只能为目录类型");
            }
            return;
        }
        //按钮
        if (menu.getType() == MenuConstant.MenuType.BUTTON.getValue()) {
            if (parentType != MenuConstant.MenuType.MENU.getValue()) {
                throw new BaseException("上级菜单只能为菜单类型");
            }
        }
    }
}
